﻿using BootstrapBlazor.Components;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.SignalR.Client;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Microsoft.Extensions.Localization;
using System.Diagnostics.CodeAnalysis;
using System.Reflection.Metadata;
using TrackSystem.Contracts;
using TrackSystem.Entities.Dtos.Channel;
using TrackSystem.Entities.Dtos.Equip;
using TrackSystem.Entities.Dtos.Logic;
using TrackSystem.Entities.Dtos.Loop;
using TrackSystem.Entities.Dtos.Sensor;
using TrackSystem.Entities.Extensions;
using TrackSystem.UI.Server.HttpRepository.Equip;
using TrackSystem.UI.Server.HttpRepository.Sensor;


namespace TrackSystem.UI.Server.Pages.Configuration
{
    public partial class EquipTable
    {
        /// <summary>
        /// 获得/设置 分页配置数据源
        /// </summary>
        private static IEnumerable<int> PageItemsSource => new int[] { 10, 20, 40 };

        private IEnumerable<SelectedItem> lstProtocol = new List<SelectedItem>();

        [Inject]
        [NotNull]
        public required IEquiplHttpRepository repo { get; set; }

        [Inject]
        [NotNull]
        public required ISensorHttpRepository sensorRepo { get; set; }

        [Inject]
        [NotNull]
        private ToastService? ToastService { get; set; }

        protected override async Task OnInitializedAsync()
        {
            if (repo == null)
            {
                throw new InvalidOperationException("Repository is not initialized.");
            }

            var protocols = Enum.GetValues(typeof(ProtocolEnum));
            foreach ( var protocol in protocols) {
                lstProtocol = lstProtocol.Append(new SelectedItem()
                {
                    Text = protocol.ToString(),
                    Value = ((int)protocol).ToString()
                });
            }

            // 初始化数据
            await base.OnInitializedAsync();
        }

        private async Task<QueryData<EquipWithSensorsDto>> OnQueryAsync(QueryPageOptions options)
        {
            if (repo == null)
            {
                await ToastService.Error("通道列表", "数据库未初始化");
                return new QueryData<EquipWithSensorsDto>();
            }

            var items = await repo.GetAllWithSensors();

            items = items.Where(options.ToFilterFunc<EquipWithSensorsDto>());

            // 排序
            var isSorted = false;
            if (!string.IsNullOrEmpty(options.SortName))
            {
                items = items.Sort(options.SortName, options.SortOrder);
                isSorted = true;
            }

            var total = items.Count();
            var result = new QueryData<EquipWithSensorsDto>()
            {
                Items = items.Skip((options.PageIndex - 1) * options.PageItems).Take(options.PageItems).ToList(),
                TotalCount = total,
                IsFiltered = true,
                IsSorted = isSorted,
                IsSearch = true
            };

            return result;
        }


        private async Task<bool> OnSaveAsync(EquipWithSensorsDto eqp, ItemChangedType changedType)
        {
            if (repo == null)
            {
                await ToastService.Error("通道列表", "数据库未初始化");
                return false;
            }

            var ret = false;
            if (changedType == ItemChangedType.Add)
            {
                var result = await repo.InsertAsync(eqp);
                if (!result.Success)
                {
                    await ToastService.Error("通道列表", result.Message);
                }
                return result.Success;
            }
            else if (changedType == ItemChangedType.Update)
            {
                var result = await repo.UpdateAsync(eqp);
                if (!result.Success)
                {
                    await ToastService.Error("通道列表", result.Message);
                }
                return result.Success;
            }

            return await Task.FromResult(ret);
        }

        private async Task<bool> OnDeleteAsync(IEnumerable<EquipWithSensorsDto> eqps)
        {
            if (repo == null)
            {
                await ToastService.Error("通道列表", "数据库未初始化");
                return false;
            }

            bool ret = true;
            foreach(var item in eqps)
            {
                var result = await repo.DeleteAsync(item.Id);
                if (!result.Success)
                {
                    await ToastService.Error("通道列表", result.Message);
                    ret = false;
                }
            }
            return ret;
        }



        [Inject]
        [NotNull]
        public DialogService? DialogService { get; set; }


        private async Task SkipToSensor(int id)
        {
            var result = await sensorRepo.GetSingleSensor(id);
            if(!result.Success)
            {
                return;
            }
            var Sensor = result.Data ??= new SensorWithChannelDto();
            var option = new EditDialogOption<SensorWithChannelDto>()
            {
                Title = "传感器信息",
                Model = Sensor,
                RowType = RowType.Inline,
                ShowLoading = true,
                ItemsPerRow = 2,
                ItemChangedType = ItemChangedType.Update,
                OnEditAsync = async context =>
                {
                    var ret = await sensorRepo.UpdateAsync((SensorWithChannelDto)context.Model);
                    if (!result.Success)
                    {
                        await ToastService.Error($"传感器{Sensor.Name}", result.Message);
                        return false;
                    }

                    await ToastService.Success($"传感器{Sensor.Name}", "数据更新成功");
                    return true;
                }
            };
            await DialogService.ShowEditDialog(option);
        }



        private HubConnection logicHub;

        private async Task SkipToLogic(int id)
        {
            try
            {
                // 建立SIGNALR连接
                logicHub = new HubConnectionBuilder()
                        .WithUrl("http://localhost:5000/logichub")
                        .WithAutomaticReconnect([TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(3)])
                        .Build();

                 await logicHub.StartAsync();

                // 发送请求
                logicHub.On<LogicDto>("RecvSingle",
                    async (result) =>
                    {
                        var option = new EditDialogOption<LogicDto>()
                        {
                            Title = "逻辑表达式",
                            Model = result,
                            RowType = RowType.Inline,
                            ShowLoading = true,
                            ItemsPerRow = 2,
                            ItemChangedType = ItemChangedType.Update,
                            OnEditAsync =  async context =>
                            {
                                logicHub.On<ApiResult<LogicDto>>("RecvUpdateLogic", (content) =>
                                {
                                    InvokeAsync(async () =>
                                    {
                                        if (content.Success)
                                        {
                                            await ToastService.Success("逻辑表达式", "更新成功");
                                        }
                                        else
                                        {
                                            await ToastService.Error("逻辑表达式", content.Message);
                                        }
                                    });
                                });

                                await logicHub.SendAsync("UpdateLogicAsync", context.Model);
                                return true;
                            }
                        };
                        await DialogService.ShowEditDialog(option);
                    });

                await logicHub.SendAsync("GetSingleAsync", id);
            }
            catch (Exception ex)
            {
                await ToastService.Error(ex.Message);
            }
        }

        private HubConnection? loopHub;

        private async Task SkipToLoop(int id)
        {
            try
            {
                // 建立SIGNALR连接
                loopHub = new HubConnectionBuilder()
                        .WithUrl("http://localhost:5000/loophub")
                        .WithAutomaticReconnect([TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(3)])
                        .Build();

                await loopHub.StartAsync();

                // 发送请求
                loopHub.On<LoopDto>("RecvSingle",
                    async (result) =>
                    {
                        var option = new EditDialogOption<LoopDto>()
                        {
                            Title = "控制回路",
                            Model = result,
                            RowType = RowType.Inline,
                            ShowLoading = true,
                            ItemsPerRow = 2,
                            ItemChangedType = ItemChangedType.Update,
                            OnEditAsync = async context =>
                            {
                                loopHub.On<ApiResult<LoopDto>>("RecvUpdateLoop", (content) =>
                                {
                                    InvokeAsync(async () =>
                                    {
                                        if (content.Success)
                                        {
                                            await ToastService.Success("控制回路", "更新成功");
                                        }
                                        else
                                        {
                                            await ToastService.Error("控制回路", content.Message);
                                        }
                                    });
                                });

                                await loopHub.SendAsync("UpdateLoopAsync", context.Model);
                                return true;
                            }
                        };
                        await DialogService.ShowEditDialog(option);
                    });

                await loopHub.SendAsync("GetSingleAsync", id);
            }
            catch (Exception ex)
            {
                await ToastService.Error(ex.Message);
            }
        }

    }
}
